// eee.Sheffield.PZ.Imaging
//
// Copyright ?Ping Zou, 2007
// sg71.cherub@gmail.com

using System;
using System.Collections.Generic;
using System.Text;
using eee.Sheffield.PZ.Math;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace eee.Sheffield.PZ.Imaging.ImageFilter
{
    public class Erosion : ImageFilter//, IGraylevelImageFilter
    {
        #region Fields
        private bool[,] _kernel;
        #endregion

        #region Fields
        #endregion

        #region Constructor
        public Erosion()
        {
            PrepareKernel();
            _flag = "[Image -> Morphology -> Erosion]";
        }
        #endregion

        #region Apply filter
        protected override PZMath_matrix ApplyDoubleGraylevelImageFilter(PZMath_matrix srcMatrix, out string logText)
        {
            int hk = _kernel.GetLength(1);
            int wk = _kernel.GetLength(0);
            int halfHk = (hk - 1) / 2;
            int halfWk = (wk - 1) / 2;
            int height = srcMatrix.RowCount;
            int width = srcMatrix.ColumnCount;

            PZMath_matrix expandSrcMatrix = srcMatrix.BoundFillingBackgroundIntensityExpand(hk, wk, 255);
            bool[,] expandSrcBoolMatrix = expandSrcMatrix.ConvertToBoolMatrix(125);

            // prepare dst bool matrix
            int expandHeight = expandSrcBoolMatrix.GetLength(1);
            int expandWidth = expandSrcBoolMatrix.GetLength(0);
            bool[,] expandDstBoolMatrix = new bool[expandWidth, expandHeight];

            int xStart = halfWk;
            int xEnd = width + halfWk;
            int yStart = halfHk;
            int yEnd = height + halfHk;

            for (int x = xStart; x < xEnd; x++)
            {
                for (int y = yStart; y < yEnd; y++)
                {
                    bool isHit = true;
                    // inside kernel
                    for (int kx = -1 * halfWk; kx <= halfWk; kx++)
                    {
                        for (int ky = -1 * halfHk; ky <= halfHk; ky++)
                        {
                            // kernel is a double[,]
                            // expandSrcBoolMatrix, and expandDstBoolMatrix are bool[,]
                            if (!expandSrcBoolMatrix[x + kx, y + ky] && _kernel[kx + halfWk, ky + halfHk])
                            {
                                isHit = false;
                                break;
                            }
                        }
                    }
                    expandDstBoolMatrix[x, y] = isHit;
                }
            }

            PZMath_matrix expandDstMatrix = new PZMath_matrix(expandDstBoolMatrix);
            PZMath_matrix dstMatrix = expandDstMatrix.BoundFillingBackgroundIntensityShrink(hk, wk);
            logText = "succed";

            return dstMatrix;
        } // ApplyDoubleGraylevelImageFilter()

        protected override PZMath_matrix[] ApplyDoubleColourImageFilter(PZMath_matrix[] srcMatrixArray, out string logText)
        {
            // TODO: add this function
            throw new Exception("The method or operation is not implemented.");
        } // ApplyDoubleColourImageFilter()
        #endregion

        #region prepare kernel
        /// <summary>
        /// prepare kernels
        /// </summary>
        private void PrepareKernel()
        {
            _kernel = new bool[,]
            {
                {false, true, false},
                {true, true, true},
                {false, true, false}
            };
        } // PrepareKernel()
        #endregion
    }
}
